package com.whfc.common.weixin.mp;

import com.alibaba.fastjson.JSON;
import com.whfc.common.util.JSONUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class WXBizDataCrypt {

    private static Logger logger = LoggerFactory.getLogger(WXBizDataCrypt.class);

    /**
     * 小程序解密算法
     *
     * @param sessionKey
     * @param encryptedData
     * @param ivs
     * @return
     * @throws Exception
     */
    public static String decrypt(String sessionKey, String encryptedData, String ivs) {

        String userInfoStr = "";

        try {

            Base64.Decoder base64Decoder = Base64.getDecoder();

            byte[] keyBytes = base64Decoder.decode(sessionKey);

            byte[] dataBytes = base64Decoder.decode(encryptedData);

            byte[] ivBytes = base64Decoder.decode(ivs);

            SecretKeySpec keyspec = new SecretKeySpec(keyBytes, "AES");
            IvParameterSpec ivspec = new IvParameterSpec(ivBytes);

            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);

            byte[] original = cipher.doFinal(dataBytes);
            String originalString = new String(original);
            userInfoStr = unpad(originalString);
        } catch (Exception e) {
            logger.error("小程序解密异常!", e);
        }
        return userInfoStr;
    }

    public static WxMpUserInfo decryptMpUsrInfo(String sessionKey, String encryptedData, String ivs) {

        String userInfoStr = decrypt(sessionKey, encryptedData, ivs);
        logger.info("解析微信小程序用户信息:{}", userInfoStr);
        WxMpUserInfo userInfo = JSON.parseObject(userInfoStr, WxMpUserInfo.class);

        return userInfo;
    }

    private static String unpad(String decryptedStr) {

        char c = decryptedStr.charAt(decryptedStr.length() - 1);

        int pading = (int) c;

        decryptedStr = decryptedStr.substring(0, decryptedStr.length() - pading);

        return decryptedStr;
    }

    public static void main(String[] args) throws Exception {

        String encryptedData = "CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZMQmRzooG2xrDcvSnxIMXFufNstNGTyaGS9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+3hVbJSRgv+4lGOETKUQz6OYStslQ142dNCuabNPGBzlooOmB231qMM85d2/fV6ChevvXvQP8Hkue1poOFtnEtpyxVLW1zAo6/1Xx1COxFvrc2d7UL/lmHInNlxuacJXwu0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn/Hz7saL8xz+W//FRAUid1OksQaQx4CMs8LOddcQhULW4ucetDf96JcR3g0gfRK4PC7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns/8wR2SiRS7MNACwTyrGvt9ts8p12PKFdlqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYVoKlaRv85IfVunYzO0IKXsyl7JCUjCpoG20f0a04COwfneQAGGwd5oa+T8yO5hzuyDb/XcxxmK01EpqOyuxINew==";

        String iv = "r7BXXKkLb8qrSNn05n0qiA==";

        String sessionKey = "tiihtNczf5v6AKRyjwEUhQ==";

        String str = WXBizDataCrypt.decrypt(sessionKey, encryptedData, iv);

        System.out.println(JSONUtil.toString(JSON.parseObject(str)));

        WxMpUserInfo userInfo = WXBizDataCrypt.decryptMpUsrInfo(sessionKey, encryptedData, iv);

        System.out.println(JSONUtil.toString(userInfo));
    }
}
